#ifndef _DSWFWDSESSION_H
#define _DSWFWDSESSION_H

#include <libtcpcombase/tcpcombase.h>

typedef enum{
	EN_MSG,
	EN_VDATA,
	EN_ADATA,
} EN_D_TYPE;

typedef struct{
	EN_D_TYPE ntype;
	int nlen;
	char* pdata;
} ST_SEND_NODE_T, *LPST_SEND_NODE_T;;

class CDswfwdsession : public CTcpcombase
{
public:
	CDswfwdsession();
	virtual ~CDswfwdsession();
public:
	CDswfwdsession(LPST_ENV_T pEnv, struct bufferevent * pBev, int nHeadSize, char* pHost, int nPort,
		EN_MISSION_TYPE nType, CB_ON_MISSION_NOTIFY pFunc, void* pParent,
		int nChId, int nSubId, char* pP2PPucId);
	static CDswfwdsession* createNew(LPST_ENV_T pEnv, char* pHost, int nPort,
		EN_MISSION_TYPE nType, CB_ON_MISSION_NOTIFY pFunc, void* pParent,
		int nChId, int nSubId, char* pP2PPucId);
private:
	static void cbCheckTask(int fd, short events, void* ctx){((CDswfwdsession*)ctx)->CheckTask(fd, events);};
	void CheckTask(int fd, short events);
	virtual int MakePayloadLength(char* pData, int nLen){m_nMsgFlag = pData[0];return (pData[4] << 24 | pData[3] << 16 | pData[2] << 8 | pData[1]);};
	virtual bool ProcessMessage(char* pMsg, int nLen, struct evbuffer *outbuf);
	virtual void OnError(EN_ERR_TYPE nType, struct bufferevent *bev, short events);
	virtual void OnConnect(struct bufferevent * bev, short events);
	void Make_TransLogin(CMarkup &xml, char* pP2PPucId);
	void SendData(EN_D_TYPE nType, char* pData, int nLen);

	bool DealStartTransResp(void* pMsgReq, const char* pMsgResp);
	bool DealStopTransReq(void* pMsgReq, const char* pMsgResp);
	static void* cbVideoSendThread(void* pvoid){((CDswfwdsession*)pvoid)->VideoSendThread();return NULL;};
	void VideoSendThread();
	void SendVideoFrame(LPST_VIDEO_FRAME_T pVideoFrame, int nFrameId);
	void SendAudioFrame(LPST_AUDIO_FRAME_T pAudioFrame, int nFrameId);
	void CheckNewTrans();

	static void cbCheckSendTask(int fd, short events, void* ctx){((CDswfwdsession*)ctx)->CheckSendTask(fd, events);};
	void CheckSendTask(int fd, short events);

	virtual void OnWrite(struct bufferevent *bev);

public:
	void AddNewTransOrder(char* pP2PPucId);
	void SetTransEnd(){pthread_mutex_lock(&m_nEndThreadLock);m_bEndThread = true;pthread_mutex_unlock(&m_nEndThreadLock);};
	char* GetKey(){return m_sKey;};
	static bool cbDealStartTransResp(void* pMsgReq, const char* pMsgResp, void* pCaller){return ((CDswfwdsession*)pCaller)->DealStartTransResp((char*)pMsgReq, pMsgResp);};
	static bool cbDealStopTransReq(void* pMsgReq, const char* pMsgResp, void* pCaller){return ((CDswfwdsession*)pCaller)->DealStopTransReq((char*)pMsgReq, pMsgResp);};
private:
	CB_ON_MISSION_NOTIFY m_pNotifyFunc;
	void* m_pParent;
	ST_MISSION_NOTIFY_T m_nNotifyParam;
	int m_nChId, m_nSubId;
	char m_sP2PPucId[64];
	char m_sKey[64];
	timer_param_t m_nTaskCheck;
	bool m_bEndThread;
	pthread_mutex_t m_nEndThreadLock;
	char m_nMsgFlag;

	pthread_mutex_t m_nLock;
	std::list<char*> m_nNewTransList;

	pthread_t m_nTransThread_id;
	int m_audio_packetcount;
	ST_AUDIO_FRAME_T m_nAudio_Send;

	std::list<LPST_SEND_NODE_T> m_nFrameList;
	pthread_mutex_t m_nSendLock;
	timer_param_t m_nTaskSend;
};

#endif

